package com.example.ourradio;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.NavUtils;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar.Tab;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

public class FeedActivity extends ActionBarActivity 
	implements 
		FeedFragment.OnFragmentInteractionListener,
		AudioFragment.OnFragmentInteractionListener {
	
	public final static String EXTRA_SUMMARY = "com.example.ourradio.SUMMARY";
	public final static String EXTRA_KEY = "com.example.ourradio.KEY";
	
	public static final String WIFI = "Wi-Fi";
    public static final String ANY = "Any";
    
    // Whether there is a Wi-Fi connection.
    private static boolean wifiConnected = false; 
    // Whether there is a mobile connection.
    private static boolean mobileConnected = false;
    // Whether the display should be refreshed.
    public static boolean refreshDisplay = true;
    
    // The user's current network preference setting.
    public static String sPref = WIFI;
    
    // The BroadcastReceiver that tracks network connectivity changes.
    private NetworkReceiver receiver = new NetworkReceiver();
    
    private FeedTab mTab;
	private Feed mFeed = new Feed();
	private Feed mSpeech = new Feed();
	
	private AudioFragment audioFrag = null;
	
	private FeedFragmentPagerAdapter mAdapter;
	private ViewPager mPager;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_feed);
        
		// Get audio fragment
		audioFrag = (AudioFragment)getSupportFragmentManager()
			.findFragmentById(R.id.fragment_audio);

		// Set up swipe views
		mAdapter = new FeedFragmentPagerAdapter(getSupportFragmentManager());
        mPager = (ViewPager)findViewById(R.id.feed_pager);
        mPager.setAdapter(mAdapter);
        mPager.setOnPageChangeListener(
        	new ViewPager.SimpleOnPageChangeListener() {
        		@Override
                public void onPageSelected(int position) {
        			// When swiping between pages, select the
                    // corresponding tab.
        			mTab = FeedTab.values()[position];
        			getSupportActionBar().setSelectedNavigationItem(position);
                }
            }
        );

		// Set up tab in action bar.
		ActionBar actionBar = getSupportActionBar();
	    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
	    ActionBar.TabListener tabListener = new ActionBar.TabListener() {
			@Override
			public void onTabUnselected(Tab tab, FragmentTransaction ft) {
			}
			
			@Override
			public void onTabSelected(Tab tab, FragmentTransaction ft) {
				mTab = FeedTab.values()[tab.getPosition()];
				mPager.setCurrentItem(tab.getPosition());
		    }
			
			@Override
			public void onTabReselected(Tab tab, FragmentTransaction ft) {
			}
		};
	    for (FeedTab tab : FeedTab.values()) {
	        actionBar.addTab(
	        	actionBar.newTab()
	            .setText(tab.toString())
	            .setTabListener(tabListener)
	        );
	    }
	    mTab = FeedTab.FEED;
	    
		// Registers BroadcastReceiver to track network connection changes.
        IntentFilter filter = 
        	new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        receiver = new NetworkReceiver();
        this.registerReceiver(receiver, filter);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();
		// Unregisters BroadcastReceiver when app is destroyed.
		if (receiver != null) {
			this.unregisterReceiver(receiver);
		}	
    }

	@Override
	protected void onPause() {
		super.onPause();
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.feed, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home:
			// This ID represents the Home or Up button. In the case of this
			// activity, the Up button is shown. Use NavUtils to allow users
			// to navigate up one level in the application structure. For
			// more details, see the Navigation pattern on Android Design:
			//
			// http://developer.android.com/design/patterns/navigation.html#up-vs-back
			//
			NavUtils.navigateUpFromSameTask(this);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	// Refreshes the display if the network connection and the
    // pref settings allow it.
    private void updateConnectedFlags() {
        ConnectivityManager connMgr = (ConnectivityManager) 
        		getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeInfo = connMgr.getActiveNetworkInfo();
        
    	// Gets the user's network preference settings
        SharedPreferences sharedPrefs = 
        	PreferenceManager.getDefaultSharedPreferences(this);
        
        // Retrieves a string value for the preferences. The second parameter
        // is the default value to use if a preference value is not found.
        sPref = sharedPrefs.getString("listPref", "Wi-Fi");

        // Checks the network connection and sets the wifiConnected and 
        // mobileConnected variables accordingly. 
        if (activeInfo != null && activeInfo.isConnected()) {
            wifiConnected = 
            	activeInfo.getType() == ConnectivityManager.TYPE_WIFI;
            mobileConnected = 
            	activeInfo.getType() == ConnectivityManager.TYPE_MOBILE;
        } else {
            wifiConnected = false;
            mobileConnected = false;
        }  
    }
    
    public boolean isNetworkAvailable() {
    	if (!refreshDisplay) {
    		return false;
    	}
	
    	updateConnectedFlags();
    	
    	return 
    		(sPref.equals(ANY) && (wifiConnected || mobileConnected)) || 
    		(sPref.equals(WIFI) && wifiConnected);
    }
    
    @Override
	public void onItemClick(int position) {
		//Intent browserIntent = new Intent(
		//	Intent.ACTION_VIEW, 
		//	Uri.parse(mFeed.mItems[position].mLink)
		//);
		//startActivity(browserIntent);
    	
    	if (audioFrag == null) {
    		return;
    	}
    	
    	Feed feed = getContents();    	
    	feed.setActivePosition(position);
    	String speechLink = feed.getActiveItem().mSpeechLink;
    	if (speechLink != null) {
    		audioFrag.playMediaPlayAudio(speechLink);
    	} else {
    		audioFrag.playTTSAudio(feed.getActiveItem().mSummary);
    	}    	
	}
	
	public Feed getContents() {
		switch (mTab) {
		case FEED: return mFeed;  
		case SPEECH: return mSpeech;
		default: return mFeed;
		}
	}
	
	@Override
	public void onLoadCompletion(Feed feed, FeedTab tab) {
		switch (tab) {
		case FEED: mFeed = feed; break;  
		case SPEECH: mSpeech = feed; break;  
		}		
	}

	@Override
	public void onNextItem(AudioFragment.Order order) {
		Feed feed = getContents();
		switch (order) {
		case SEQUENCE: 
			feed.incPosition();
			break;
		case SINGLE: 
			break;
		case RANDOM: 
			feed.randomPosition();
			break;
		}
		onItemClick(feed.getActivePosition());
	}

	@Override
	public void onRecordItem() {
		Feed feed = getContents();
		Intent intent = new Intent(this, RecorderActivity.class);
		intent.putExtra(
			EXTRA_SUMMARY, 
			feed.getActiveItem().mSummary
		);
		intent.putExtra(
			EXTRA_KEY, 
			feed.getActiveItem().mKey
		);
	    startActivity(intent);	    
	}
	
	public class NetworkReceiver extends BroadcastReceiver {
    	public NetworkReceiver() {
    	}

    	@Override
    	public void onReceive(Context context, Intent intent) {
    	    ConnectivityManager conn =  (ConnectivityManager)
    	        context.getSystemService(Context.CONNECTIVITY_SERVICE);
    	    NetworkInfo networkInfo = conn.getActiveNetworkInfo();
    	       
    	    // Checks the user prefs and the network connection. Based on the 
    	    // result, decides whether to refresh the display or keep the 
    	    // current display. If the userpref is Wi-Fi only, checks to see if 
    	    // the device has a Wi-Fi connection.
    	    if (WIFI.equals(sPref) && networkInfo != null && 
    	    	networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
    	        // If device has its Wi-Fi connection, sets refreshDisplay
    	        // to true. This causes the display to be refreshed when the 
    	    	// user returns to the app.
    	        refreshDisplay = true;
    	        Toast.makeText(
    	        	context, 
    	        	R.string.wifi_connected, 
    	        	Toast.LENGTH_SHORT
    	        ).show();

    	    // If the setting is ANY network and there is a network connection
    	    // (which by process of elimination would be mobile), sets 
    	    // refreshDisplay to true.
    	    } else if (ANY.equals(sPref) && networkInfo != null) {
    	        refreshDisplay = true;
    	                 
    	    // Otherwise, the app can't download content--either because there 
    	    // is no network connection (mobile or Wi-Fi), or because the pref 
    	    // setting is WIFI, and there is no Wi-Fi connection. Sets 
    	    // refreshDisplay to false.
    	    } else {
    	        refreshDisplay = false;
    	        Toast.makeText(
    	        	context, 
    	        	R.string.lost_connection, 
    	        	Toast.LENGTH_SHORT
    	        ).show();
    	    }
    	}
    }
}
